// Game constants
const COLS = 10;
const ROWS = 20;
const BLOCK_SIZE = 30;

// Tetromino shapes
const SHAPES = [
    [[1, 1, 1, 1]], // I
    [[1, 1], [1, 1]], // O
    [[0, 1, 0], [1, 1, 1]], // T
    [[1, 1, 0], [0, 1, 1]], // S
    [[0, 1, 1], [1, 1, 0]], // Z
    [[1, 0, 0], [1, 1, 1]], // J
    [[0, 0, 1], [1, 1, 1]]  // L
];

// Colors for each tetromino
const COLORS = [
    '#00f0f0', // I - Cyan
    '#f0f000', // O - Yellow
    '#a000f0', // T - Purple
    '#00f000', // S - Green
    '#f00000', // Z - Red
    '#0000f0', // J - Blue
    '#f0a000'  // L - Orange
];

class Game {
    constructor() {
        this.canvas = document.getElementById('gameCanvas');
        this.ctx = this.canvas.getContext('2d');
        this.board = this.createBoard();
        this.currentPiece = this.createPiece();
        this.gameOver = false;
        this.score = 0;
        this.level = 1;
        this.lines = 0;
        this.dropCounter = 0;
        this.dropInterval = 1000;
        this.lastTime = 0;
        this.paused = false;

        this.setupEventListeners();
        this.updateDisplay();
    }

    createBoard() {
        return Array.from({ length: ROWS }, () => Array(COLS).fill(0));
    }

    createPiece() {
        const typeId = Math.floor(Math.random() * SHAPES.length);
        return {
            shape: SHAPES[typeId],
            color: COLORS[typeId],
            x: Math.floor(COLS / 2) - 1,
            y: 0
        };
    }

    drawBoard() {
        this.ctx.clearRect(0, 0, this.canvas.width, this.canvas.height);

        // Draw grid lines
        this.drawGrid();

        // Draw placed pieces
        this.board.forEach((row, y) => {
            row.forEach((value, x) => {
                if (value) {
                    this.drawBlock(x, y, COLORS[value - 1]);
                }
            });
        });

        // Draw current piece
        this.currentPiece.shape.forEach((row, y) => {
            row.forEach((value, x) => {
                if (value) {
                    this.drawBlock(
                        this.currentPiece.x + x,
                        this.currentPiece.y + y,
                        this.currentPiece.color
                    );
                }
            });
        });
    }

    drawBlock(x, y, color) {
        this.ctx.fillStyle = color;
        this.ctx.fillRect(x * BLOCK_SIZE, y * BLOCK_SIZE, BLOCK_SIZE, BLOCK_SIZE);
        this.ctx.strokeStyle = 'rgba(255, 255, 255, 0.3)';
        this.ctx.strokeRect(x * BLOCK_SIZE, y * BLOCK_SIZE, BLOCK_SIZE, BLOCK_SIZE);
    }

    drawGrid() {
        this.ctx.strokeStyle = 'rgba(255, 255, 255, 0.1)';
        this.ctx.lineWidth = 1;

        // Draw vertical grid lines
        for (let x = 0; x <= COLS; x++) {
            this.ctx.beginPath();
            this.ctx.moveTo(x * BLOCK_SIZE, 0);
            this.ctx.lineTo(x * BLOCK_SIZE, ROWS * BLOCK_SIZE);
            this.ctx.stroke();
        }

        // Draw horizontal grid lines
        for (let y = 0; y <= ROWS; y++) {
            this.ctx.beginPath();
            this.ctx.moveTo(0, y * BLOCK_SIZE);
            this.ctx.lineTo(COLS * BLOCK_SIZE, y * BLOCK_SIZE);
            this.ctx.stroke();
        }
    }

    movePiece(dx, dy) {
        if (this.paused || this.gameOver) return;

        this.currentPiece.x += dx;
        this.currentPiece.y += dy;

        if (this.collision()) {
            this.currentPiece.x -= dx;
            this.currentPiece.y -= dy;

            if (dy > 0) {
                this.lockPiece();
                this.clearLines();
                this.currentPiece = this.createPiece();
                if (this.collision()) {
                    this.gameOver = true;
                    alert('Game Over!');
                }
            }
            return false;
        }
        return true;
    }

    rotatePiece() {
        if (this.paused || this.gameOver) return;

        const originalShape = this.currentPiece.shape;
        const rows = originalShape.length;
        const cols = originalShape[0].length;

        // Create rotated matrix
        const rotated = Array.from({ length: cols }, (_, y) =>
            Array.from({ length: rows }, (_, x) =>
                originalShape[rows - 1 - x][y]
            )
        );

        const originalShapeBackup = this.currentPiece.shape;
        this.currentPiece.shape = rotated;

        if (this.collision()) {
            // Try wall kicks
            const kicks = [-1, 1, -2, 2];
            for (let kick of kicks) {
                this.currentPiece.x += kick;
                if (!this.collision()) return;
                this.currentPiece.x -= kick;
            }
            // If all kicks fail, revert rotation
            this.currentPiece.shape = originalShapeBackup;
        }
    }

    collision() {
        return this.currentPiece.shape.some((row, y) => {
            return row.some((value, x) => {
                if (value === 0) return false;

                const newX = this.currentPiece.x + x;
                const newY = this.currentPiece.y + y;

                return (
                    newX < 0 ||
                    newX >= COLS ||
                    newY >= ROWS ||
                    (newY >= 0 && this.board[newY][newX])
                );
            });
        });
    }

    lockPiece() {
        this.currentPiece.shape.forEach((row, y) => {
            row.forEach((value, x) => {
                if (value) {
                    const boardY = this.currentPiece.y + y;
                    if (boardY >= 0) {
                        this.board[boardY][this.currentPiece.x + x] =
                            COLORS.indexOf(this.currentPiece.color) + 1;
                    }
                }
            });
        });
    }

    clearLines() {
        let linesCleared = 0;

        for (let y = ROWS - 1; y >= 0; y--) {
            if (this.board[y].every(value => value !== 0)) {
                this.board.splice(y, 1);
                this.board.unshift(Array(COLS).fill(0));
                linesCleared++;
                y++; // Check the same line again
            }
        }

        if (linesCleared > 0) {
            this.lines += linesCleared;
            this.score += [0, 40, 100, 300, 1200][linesCleared] * this.level;
            this.level = Math.floor(this.lines / 10) + 1;
            this.dropInterval = Math.max(100, 1000 - (this.level - 1) * 100);
            this.updateDisplay();
        }
    }

    hardDrop() {
        if (this.paused || this.gameOver) return;

        while (this.movePiece(0, 1)) {
            // Continue dropping until collision
        }
    }

    update(time = 0) {
        if (this.paused || this.gameOver) return;

        const deltaTime = time - this.lastTime;
        this.lastTime = time;

        this.dropCounter += deltaTime;
        if (this.dropCounter > this.dropInterval) {
            this.movePiece(0, 1);
            this.dropCounter = 0;
        }

        this.drawBoard();
        requestAnimationFrame(this.update.bind(this));
    }

    setupEventListeners() {
        document.addEventListener('keydown', (e) => {
            if (this.paused || this.gameOver) return;

            switch (e.key) {
                case 'ArrowLeft':
                    this.movePiece(-1, 0);
                    break;
                case 'ArrowRight':
                    this.movePiece(1, 0);
                    break;
                case 'ArrowDown':
                    this.movePiece(0, 1);
                    break;
                case 'ArrowUp':
                    this.rotatePiece();
                    break;
                case ' ':
                    this.hardDrop();
                    break;
            }
        });

        document.getElementById('startBtn').addEventListener('click', () => {
            if (this.gameOver) {
                this.reset();
            }
            this.paused = false;
            this.lastTime = 0;
            this.update();
        });

        document.getElementById('pauseBtn').addEventListener('click', () => {
            this.paused = !this.paused;
            if (!this.paused) {
                this.lastTime = 0;
                this.update();
            }
        });

        document.getElementById('resetBtn').addEventListener('click', () => {
            this.reset();
        });
    }

    reset() {
        this.board = this.createBoard();
        this.currentPiece = this.createPiece();
        this.gameOver = false;
        this.score = 0;
        this.level = 1;
        this.lines = 0;
        this.dropInterval = 1000;
        this.paused = false;
        this.updateDisplay();
        this.drawBoard();
    }

    updateDisplay() {
        document.getElementById('score').textContent = this.score;
        document.getElementById('level').textContent = this.level;
        document.getElementById('lines').textContent = this.lines;
    }
}

// Initialize the game when the page loads
document.addEventListener('DOMContentLoaded', () => {
    const game = new Game();
    game.drawBoard();
});